#include <stdio.h>
#include "../include/mergeToVx.h"/*winie*/
#include "../include/target_defines.h"


#include "../include/wtapi_type.h"
#include "../include/wtapi_lowlevel.h"
#ifdef guid
HANDLE	OpenByInterface(GUID* pClassGuid, DWORD instance, PDWORD pError);
#endif
HANDLE	hDevice[nMaxDevice] = {INVALID_HANDLE_VALUE,INVALID_HANDLE_VALUE,
                               INVALID_HANDLE_VALUE,INVALID_HANDLE_VALUE,
                               INVALID_HANDLE_VALUE,INVALID_HANDLE_VALUE,
                               INVALID_HANDLE_VALUE,INVALID_HANDLE_VALUE};

HANDLE	Thread[nMaxDevice]={INVALID_HANDLE_VALUE,INVALID_HANDLE_VALUE,
                               INVALID_HANDLE_VALUE,INVALID_HANDLE_VALUE,
                               INVALID_HANDLE_VALUE,INVALID_HANDLE_VALUE,
                               INVALID_HANDLE_VALUE,INVALID_HANDLE_VALUE};

HANDLE	hEvent[nMaxDevice];
#ifdef guid
GUID	ClassGuid = WtdriverDevice_CLASS_GUID;
#endif

//static	UINT IrqEventIdx[nMaxDevice]={nMax_IRQEvent_Handle,nMax_IRQEvent_Handle,nMax_IRQEvent_Handle,nMax_IRQEvent_Handle,nMax_IRQEvent_Handle,nMax_IRQEvent_Handle,nMax_IRQEvent_Handle,nMax_IRQEvent_Handle};

static	WT_UserHandle	pUserHandle[nMaxDevice][nMax_Lowlevle_Handle];

PCHAR	pCHAR_PCI_BAR[nMaxDevice][6];

volatile UINT Close_Flag[nMaxDevice]={0,0,0,0,0,0,0,0};
static struct	PCI_CONFIG_HEADER_0 pci_config_lo[nMaxDevice];
static struct pciBoardIndex pci_bord[nMaxDevice];


PVOID __stdcall Wtdriver_Memory_Map(UINT device,UINT PCI_BAR)
{
    ULONG nRead=0;
	PVOID ptr;
	int membase;
	if(device<nMaxDevice)
	{

#ifdef guid
		if(hDevice[device] != INVALID_HANDLE_VALUE )
		{
			if(PCI_BAR==0)DeviceIoControl(hDevice[device],WTDRIVER_MEMORY_MAP_BAR0,NULL,NULL,&ptr,NULL,&nRead,NULL);
			else if(PCI_BAR==1)DeviceIoControl(hDevice[device],WTDRIVER_MEMORY_MAP_BAR1,NULL,NULL,&ptr,NULL,&nRead,NULL);
			else if(PCI_BAR==2)DeviceIoControl(hDevice[device],WTDRIVER_MEMORY_MAP_BAR2,NULL,NULL,&ptr,NULL,&nRead,NULL);
			else if(PCI_BAR==3)DeviceIoControl(hDevice[device],WTDRIVER_MEMORY_MAP_BAR3,NULL,NULL,&ptr,NULL,&nRead,NULL);
			else if(PCI_BAR==4)DeviceIoControl(hDevice[device],WTDRIVER_MEMORY_MAP_BAR4,NULL,NULL,&ptr,NULL,&nRead,NULL);
			else if(PCI_BAR==5)DeviceIoControl(hDevice[device],WTDRIVER_MEMORY_MAP_BAR5,NULL,NULL,&ptr,NULL,&nRead,NULL);
		}
#endif		

 	}
	return ptr;
}

UINT  __stdcall Wtdriver_Memory_UnMap(UINT device,UINT PCI_BAR)
{
    ULONG nRead=0;
	if(device<nMaxDevice)
	{
#ifdef guid
		if(hDevice[device] != INVALID_HANDLE_VALUE )
		{
			if(PCI_BAR==0)DeviceIoControl(hDevice[device],WTDRIVER_MEMORY_UNMAP_BAR0,NULL,NULL,NULL,NULL,&nRead,NULL);
			else if(PCI_BAR==1)DeviceIoControl(hDevice[device],WTDRIVER_MEMORY_UNMAP_BAR1,NULL,NULL,NULL,NULL,&nRead,NULL);
			else if(PCI_BAR==2)DeviceIoControl(hDevice[device],WTDRIVER_MEMORY_UNMAP_BAR2,NULL,NULL,NULL,NULL,&nRead,NULL);
			else if(PCI_BAR==3)DeviceIoControl(hDevice[device],WTDRIVER_MEMORY_UNMAP_BAR3,NULL,NULL,NULL,NULL,&nRead,NULL);
			else if(PCI_BAR==4)DeviceIoControl(hDevice[device],WTDRIVER_MEMORY_UNMAP_BAR4,NULL,NULL,NULL,NULL,&nRead,NULL);
			else if(PCI_BAR==5)DeviceIoControl(hDevice[device],WTDRIVER_MEMORY_UNMAP_BAR5,NULL,NULL,NULL,NULL,&nRead,NULL);
		}
#endif
 	}
	return nRead;
}

#if 0
ULONG __stdcall Thread_Proc_0(PVOID param)
#define DEVICE_NUM	0
	#include "wtapi_lowlevel_irq_handle.h"
#undef	DEVICE_NUM

ULONG __stdcall Thread_Proc_1(PVOID param)
#define DEVICE_NUM	1
	#include "wtapi_lowlevel_irq_handle.h"
#undef	DEVICE_NUM

ULONG __stdcall Thread_Proc_2(PVOID param)
#define DEVICE_NUM	2
	#include "wtapi_lowlevel_irq_handle.h"
#undef	DEVICE_NUM

ULONG __stdcall Thread_Proc_3(PVOID param)
#define DEVICE_NUM	3
	#include "wtapi_lowlevel_irq_handle.h"
#undef	DEVICE_NUM

ULONG __stdcall Thread_Proc_4(PVOID param)
#define DEVICE_NUM	4
	#include "wtapi_lowlevel_irq_handle.h"
#undef	DEVICE_NUM

ULONG __stdcall Thread_Proc_5(PVOID param)
#define DEVICE_NUM	5
	#include "wtapi_lowlevel_irq_handle.h"
#undef	DEVICE_NUM

ULONG __stdcall Thread_Proc_6(PVOID param)
#define DEVICE_NUM	6
	#include "wtapi_lowlevel_irq_handle.h"
#undef	DEVICE_NUM

ULONG __stdcall Thread_Proc_7(PVOID param)
#define DEVICE_NUM	7
	#include "wtapi_lowlevel_irq_handle.h"
#undef	DEVICE_NUM
#endif
int WtPci_Connect(int inum, VOIDFUNCPTR * Funptr, UINT device)
{
	return pciIntConnect(INUM_TO_IVEC(inum+0x20),(VOIDFUNCPTR) Funptr, device);//sysAuxClkConnect((FUNCPTR)Funptr,device);
}
UINT __stdcall Wtdriver_Open(UINT device)
{
 //   ULONG  Error;
	char taskName[30];

	if(device<nMaxDevice)
	{

		if(hDevice[device] == INVALID_HANDLE_VALUE)
		{
			if(WtPci_Initial(device) == -1)/*set structures tobe zero*/
			{
				logMsg("pci struct initial error\r\n",0,0,0,0,0,0);
				return WT_UNSUCCESS;
			}
			hDevice[device] = WtPci_Open(&pci_config_lo[device],device);/*read all pci config*/
			if (hDevice[device] != INVALID_HANDLE_VALUE) 
			{
				Wtdriver_IrqDisable(device);

				/*for(UINT i=0;i<6;i++)
				{
					pCHAR_PCI_BAR[device][i]   = (PCHAR)Wtdriver_Memory_Map(device,i);
				}
				
				UINT rst = Wtdriver_Set_IrqEvent(device);
				if(rst==nMax_IRQEvent_Handle) 
				{
					return WT_UNSUCCESS;
				}

				IrqEventIdx[device] = rst;
				Wtdriver_Clear_IrqCount(device);
				*/
				if(Thread[device]==INVALID_HANDLE_VALUE)
				{
					for(UINT idx=0;idx<nMax_Lowlevle_Handle;idx++)pUserHandle[device][idx]=NULL;

					Close_Flag[device]=1;

					#if 0
					DWORD Td;
					if(device==0)		Thread[0] = CreateThread(NULL,0,Thread_Proc_0,NULL,0,&Td); 
					else if(device==1)	Thread[1] = CreateThread(NULL,0,Thread_Proc_1,NULL,0,&Td); 
					else if(device==2)	Thread[2] = CreateThread(NULL,0,Thread_Proc_2,NULL,0,&Td); 
					else if(device==3)	Thread[3] = CreateThread(NULL,0,Thread_Proc_3,NULL,0,&Td); 
					else if(device==4)	Thread[4] = CreateThread(NULL,0,Thread_Proc_4,NULL,0,&Td); 
					else if(device==5)	Thread[5] = CreateThread(NULL,0,Thread_Proc_5,NULL,0,&Td); 
					else if(device==6)	Thread[6] = CreateThread(NULL,0,Thread_Proc_6,NULL,0,&Td); 
					else if(device==7)	Thread[7] = CreateThread(NULL,0,Thread_Proc_7,NULL,0,&Td); 
					
					SetPriorityClass(Thread[device],HIGH_PRIORITY_CLASS);
					SetThreadPriority(Thread[device],THREAD_PRIORITY_NORMAL);
					#else 
					pci_bord[device].semPci = semCCreate(SEM_Q_FIFO,SEM_EMPTY);
					pci_bord[device].semIntFlag = 1;
					sprintf(taskName,"tPciHandle%d",device);
					Thread[device] = taskSpawn(taskName,150,0,2000,(FUNCPTR)WtPci_IntHandle,device,0,0,0,0,0,0,0,0,0);

					int ret = -1;
					ret = WtPci_Connect((int)(pci_bord[device].intNum),(VOIDFUNCPTR*)WtPci_IntFun,device);
					
					#ifdef log
					printf("device %d has %d as intNum\r\n",device,pci_bord[device].intNum);
					#endif
					#endif

				}

				Wtdriver_IrqEnable(device);
				
				return WT_SUCCESS;
			}
			else return WT_UNSUCCESS; 
		}

		return WT_SUCCESS;
	}

	else return WT_UNSUCCESS; 
}



void __stdcall Wtdriver_Close(UINT device)
{
	if(device<nMaxDevice)
	{
		if(hDevice[device] != INVALID_HANDLE_VALUE)
		{
			//Wtdriver_UnSet_IrqEvent(device);

			if(Close_Flag[device]==1)
			{
				Close_Flag[device]=0;//=2;
				while(Close_Flag[device]!=0){;}
			
				if(Thread[device]!=INVALID_HANDLE_VALUE)
				{
					//CloseHandle(Thread[device]);
					WtPci_Close(device);
					Thread[device]=INVALID_HANDLE_VALUE;
				}

				for(UINT idx=0;idx<nMax_Lowlevle_Handle;idx++)pUserHandle[device][idx]=NULL;
			}

			for(UINT i=0;i<6;i++)
			{
				Wtdriver_Memory_UnMap(device,i);
			}

			//CloseHandle(hDevice[device]);
			hDevice[device] = INVALID_HANDLE_VALUE;
		}
	}
}


#if 0
void __stdcall Wtdriver_SetThreadPriority(UINT device,int nPriority,DWORD dwPriorityClass)
{
	if(device<nMaxDevice)
	{
		SetPriorityClass(Thread[device],dwPriorityClass);
		SetThreadPriority(Thread[device],nPriority);
	}
}
#endif

void __stdcall Wtdriver_Read_PciConfig(UINT device,struct PCI_CONFIG_HEADER_0 *pci_config)
{
 //   ULONG nRead=0;
	if(device<nMaxDevice)
	{
		/*if(hDevice[device] != INVALID_HANDLE_VALUE )
		{
			DeviceIoControl(hDevice[device],
							WTDRIVER_READ_PCICONFIG,
							NULL,
							NULL,  
							pci_config,
							sizeof(struct PCI_CONFIG_HEADER_0),
							&nRead,
							NULL);
		}*/
		memcpy(pci_config,&pci_config_lo[device],sizeof(struct PCI_CONFIG_HEADER_0));		
		
 	}
}
UINT __stdcall Wtdriver_IrqEnable(UINT device)
{

	ULONG nRead=0;
	//sysAuxClkEnable();

	int nn = 0;
	nn = pci_bord[device].intNum;
	nRead  = sysIntEnablePIC(pci_bord[device].intNum);

#if 0
	if(device<nMaxDevice)
	{
		if(hDevice[device] != INVALID_HANDLE_VALUE )
		{
			DeviceIoControl(hDevice[device],
							WTDRIVER_IRQENABLE,
							NULL,
							NULL,  
							NULL,
							NULL,
							&nRead,
							NULL);
		}
 	}
#endif
	return nRead;
}

UINT __stdcall Wtdriver_IrqDisable(UINT device)
{
    ULONG nRead=0;
	//sysAuxClkDisable();

	
	nRead  = sysIntDisablePIC(pci_bord[device].intNum);
#if 0
	if(device<nMaxDevice)
	{
		if(hDevice[device] != INVALID_HANDLE_VALUE )
		{
			DeviceIoControl(hDevice[device],
							WTDRIVER_IRQDISABLE,
							NULL,
							NULL,  
							NULL,
							NULL,
							&nRead,
							NULL);
		}
 	}
#endif
	return nRead;
}
#if 0
UINT __stdcall Wtdriver_Set_IrqEvent(UINT device)
{
	ULONG nRead=0;
	hEvent[device] = CreateEvent(NULL,FALSE,FALSE,NULL);
	if(device<nMaxDevice)
	{
		if(hDevice[device] != INVALID_HANDLE_VALUE )
		{
              DeviceIoControl(hDevice[device],
			             	  WTDRIVER_SET_IRQEvent,
							  &hEvent[device],
							  sizeof(HANDLE),  
							  NULL,
							  NULL,
							  &nRead,
							  NULL);
        }
	}
	return nRead;
}

void __stdcall Wtdriver_UnSet_IrqEvent(UINT device)
{
   ULONG nRead=0;
   if(device<nMaxDevice)
	{
		/*if(hDevice[device] != INVALID_HANDLE_VALUE )
		{
              DeviceIoControl(hDevice[device],
			             	  WTDRIVER_UNSET_IRQEvent,
							  NULL,
							  IrqEventIdx[device],  
							  NULL,
							  NULL,
							  &nRead,
							  NULL);
        }*/
		IrqEventIdx[device]=nMax_IRQEvent_Handle;
   }
}

UINT __stdcall Wtdriver_Read_IrqCount(UINT device)
{
    ULONG nRead=0;
	if(device<nMaxDevice)
	{
		if(hDevice[device] != INVALID_HANDLE_VALUE )
		{
			DeviceIoControl(hDevice[device],
							WTDRIVER_READ_IRQCOUNT,
							NULL,
							NULL,  
							NULL,
							NULL,
							&nRead,
							NULL);
		}
 	}
	return nRead;
}

void __stdcall Wtdriver_Clear_IrqCount(UINT device)
{
    ULONG nRead=0;
	if(device<nMaxDevice)
	{
		if(hDevice[device] != INVALID_HANDLE_VALUE )
		{
			DeviceIoControl(hDevice[device],
							WTDRIVER_CLEAR_IRQCOUNT,
							NULL,
							NULL,  
							NULL,
							NULL,
							&nRead,
							NULL);
		}
 	}
}
#endif  /*interupt function need discuss*/

void __stdcall Wtdriver_Set_m_Ready(UINT device)
{
    ULONG nRead=0;
	if(device<nMaxDevice)
	{
#if 0
		if(hDevice[device] != INVALID_HANDLE_VALUE )
		{
			DeviceIoControl(hDevice[device],
							WTDRIVER_Set_READY,
							NULL,
							NULL,  
							NULL,
							NULL,
							&nRead,
							NULL);
		}
#endif
 	}

}


UINT __stdcall Wtdriver_Read_m_Ready(UINT device)
{
    ULONG nRead=0;
	if(device<nMaxDevice)
	{
#if 0
		if(hDevice[device] != INVALID_HANDLE_VALUE )
		{
			DeviceIoControl(hDevice[device],
							WTDRIVER_Get_READY,
							NULL,
							NULL,  
							NULL,
							NULL,
							&nRead,
							NULL);
		}
#endif
 	}
	else nRead = 1;
	return nRead;
}

UINT  __stdcall Wtdriver_SetUserHandle(UINT device,WT_UserHandle hUser)
{
	UINT idx;
	for( idx=0;idx<nMax_Lowlevle_Handle;idx++)
	{
		if(pUserHandle[device][idx]==NULL)
		{
			pUserHandle[device][idx]=hUser;
			return WT_SUCCESS;
		}
	}
	return WT_UNSUCCESS;
}

UINT  __stdcall Wtdriver_UnSetUserHandle(UINT device,WT_UserHandle hUser)
{
	UINT idx;
	for( idx=0;idx<nMax_Lowlevle_Handle;idx++)
	{
		if(pUserHandle[device][idx]==hUser)
		{
			pUserHandle[device][idx]=NULL;
			return WT_SUCCESS;
		}
	}
	return WT_UNSUCCESS;
}

PCHAR __stdcall Wtdriver_GetMapAddress(UINT device,UINT PCI_BAR)
{
	return pCHAR_PCI_BAR[device][PCI_BAR];
}

UINT __stdcall Wtdriver_Memory_Read(UINT device,PUINT ptr,UINT ofs,UINT num,UINT PCI_BAR)
{
    ULONG nRead=0;
	if(device<nMaxDevice)
	{
		nRead = WT_Read32(device,ptr,ofs,num,PCI_BAR);
#if 0
		if(hDevice[device] != INVALID_HANDLE_VALUE )
		{
			if(PCI_BAR==0)
				DeviceIoControl(hDevice[device],
							WTDRIVER_MEMORY_READ_BAR0,
							NULL,
							ofs,  
							ptr,
							num*sizeof(UINT),
							&nRead,
							NULL);
			else if(PCI_BAR==1)
				DeviceIoControl(hDevice[device],
							WTDRIVER_MEMORY_READ_BAR1,
							NULL,
							ofs,  
							ptr,
							num*sizeof(UINT),
							&nRead,
							NULL);
			else if(PCI_BAR==2)
				DeviceIoControl(hDevice[device],
							WTDRIVER_MEMORY_READ_BAR2,
							NULL,
							ofs,  
							ptr,
							num*sizeof(UINT),
							&nRead,
							NULL);
			else if(PCI_BAR==3)
				DeviceIoControl(hDevice[device],
							WTDRIVER_MEMORY_READ_BAR3,
							NULL,
							ofs,  
							ptr,
							num*sizeof(UINT),
							&nRead,
							NULL);
			else if(PCI_BAR==4)
				DeviceIoControl(hDevice[device],
							WTDRIVER_MEMORY_READ_BAR4,
							NULL,
							ofs,  
							ptr,
							num*sizeof(UINT),
							&nRead,
							NULL);
			else if(PCI_BAR==5)
				DeviceIoControl(hDevice[device],
							WTDRIVER_MEMORY_READ_BAR5,
							NULL,
							ofs,  
							ptr,
							num*sizeof(UINT),
							&nRead,
							NULL);
 		}
#endif
	}
	return nRead;
}


UINT __stdcall Wtdriver_Memory_Write(UINT device,PUINT ptr,UINT ofs,UINT num,UINT PCI_BAR)
{
    ULONG nWrite=0;
	if(device<nMaxDevice)
	{
		nWrite = WT_Write32(device,ptr,ofs,num,PCI_BAR);
#if 0
		if(hDevice[device] != INVALID_HANDLE_VALUE )
		{
			if(PCI_BAR==0)
				DeviceIoControl(hDevice[device],
							WTDRIVER_MEMORY_WRITE_BAR0,
							ptr,
							num*sizeof(UINT),
							NULL,
							ofs,  
							&nWrite,
							NULL);
			else if(PCI_BAR==1)
				DeviceIoControl(hDevice[device],
							WTDRIVER_MEMORY_WRITE_BAR1,
							ptr,
							num*sizeof(UINT),
							NULL,
							ofs,  
							&nWrite,
							NULL);
			else if(PCI_BAR==2)
				DeviceIoControl(hDevice[device],
							WTDRIVER_MEMORY_WRITE_BAR2,
							ptr,
							num*sizeof(UINT),
							NULL,
							ofs,  
							&nWrite,
							NULL);
			else if(PCI_BAR==3)
				DeviceIoControl(hDevice[device],
							WTDRIVER_MEMORY_WRITE_BAR3,
							ptr,
							num*sizeof(UINT),
							NULL,
							ofs,  
							&nWrite,
							NULL);
			else if(PCI_BAR==4)
				DeviceIoControl(hDevice[device],
							WTDRIVER_MEMORY_WRITE_BAR4,
							ptr,
							num*sizeof(UINT),
							NULL,
							ofs,  
							&nWrite,
							NULL);
			else if(PCI_BAR==5)
				DeviceIoControl(hDevice[device],
							WTDRIVER_MEMORY_WRITE_BAR5,
							ptr,
							num*sizeof(UINT),
							NULL,
							ofs,  
							&nWrite,
							NULL);
		}
#endif
	}
    return nWrite;
}

UINT __stdcall Wtdriver_IoPort_Read(UINT device,PUINT ptr,UINT ofs,UINT num,UINT PCI_BAR)
{
    ULONG nRead=0;
	if(device<nMaxDevice)
	{
		nRead = WT_Read32(device,ptr,ofs,num,PCI_BAR);
#if 0
		if(hDevice[device] != INVALID_HANDLE_VALUE )
		{
			if(PCI_BAR==0)
				DeviceIoControl(hDevice[device],
							WTDRIVER_IO_READ_BAR0,
							NULL,
							ofs,  
							ptr,
							num*sizeof(UINT),
							&nRead,
							NULL);
			else if(PCI_BAR==1)
				DeviceIoControl(hDevice[device],
							WTDRIVER_IO_READ_BAR1,
							NULL,
							ofs,  
							ptr,
							num*sizeof(UINT),
							&nRead,
							NULL);
			else if(PCI_BAR==2)
				DeviceIoControl(hDevice[device],
							WTDRIVER_IO_READ_BAR2,
							NULL,
							ofs,  
							ptr,
							num*sizeof(UINT),
							&nRead,
							NULL);
			else if(PCI_BAR==3)
				DeviceIoControl(hDevice[device],
							WTDRIVER_IO_READ_BAR3,
							NULL,
							ofs,  
							ptr,
							num*sizeof(UINT),
							&nRead,
							NULL);
			else if(PCI_BAR==4)
				DeviceIoControl(hDevice[device],
							WTDRIVER_IO_READ_BAR4,
							NULL,
							ofs,  
							ptr,
							num*sizeof(UINT),
							&nRead,
							NULL);
			else if(PCI_BAR==5)
				DeviceIoControl(hDevice[device],
							WTDRIVER_IO_READ_BAR5,
							NULL,
							ofs,  
							ptr,
							num*sizeof(UINT),
							&nRead,
							NULL);
 		}
#endif
	}
	return nRead;
}


UINT __stdcall Wtdriver_IoPort_Write(UINT device,PUINT ptr,UINT ofs,UINT num,UINT PCI_BAR)
{
    ULONG nWrite=0;
	if(device<nMaxDevice)
	{
		nWrite = WT_Write32(device,ptr,ofs,num,PCI_BAR);
#if 0
		if(hDevice[device] != INVALID_HANDLE_VALUE )
		{
			if(PCI_BAR==0)
				DeviceIoControl(hDevice[device],
							WTDRIVER_IO_WRITE_BAR0,
							ptr,
							num*sizeof(UINT),
							NULL,
							ofs,  
							&nWrite,
							NULL);
			else if(PCI_BAR==1)
				DeviceIoControl(hDevice[device],
							WTDRIVER_IO_WRITE_BAR1,
							ptr,
							num*sizeof(UINT),
							NULL,
							ofs,  
							&nWrite,
							NULL);
			else if(PCI_BAR==2)
				DeviceIoControl(hDevice[device],
							WTDRIVER_IO_WRITE_BAR2,
							ptr,
							num*sizeof(UINT),
							NULL,
							ofs,  
							&nWrite,
							NULL);
			else if(PCI_BAR==3)
				DeviceIoControl(hDevice[device],
							WTDRIVER_IO_WRITE_BAR3,
							ptr,
							num*sizeof(UINT),
							NULL,
							ofs,  
							&nWrite,
							NULL);
			else if(PCI_BAR==4)
				DeviceIoControl(hDevice[device],
							WTDRIVER_IO_WRITE_BAR4,
							ptr,
							num*sizeof(UINT),
							NULL,
							ofs,  
							&nWrite,
							NULL);
			else if(PCI_BAR==5)
				DeviceIoControl(hDevice[device],
							WTDRIVER_IO_WRITE_BAR5,
							ptr,
							num*sizeof(UINT),
							NULL,
							ofs,  
							&nWrite,
							NULL);
		}
#endif
	}
    return nWrite;
}

UINT  __stdcall Wtdriver_Get_Device_Info(UINT device,struct	WT_Device_Info *pDeviceInfo)
{
    ULONG nRead=0;
	if(device<nMaxDevice)
	{
		if(hDevice[device] != INVALID_HANDLE_VALUE )
		{
				/*DeviceIoControl(hDevice[device],
							WTDRIVER_GET_BUS_DEVICE_NUMBER,
							NULL,
							NULL,  
							pDeviceInfo,
							sizeof(struct	WT_Device_Info),
							&nRead,
							NULL);
							*/
		}
	}
    return nRead;
}

UINT  __stdcall Wtdriver_Set_Device_Info(UINT device,struct	WT_Device_Info *pDeviceInfo)
{
    ULONG nWrite=0;

	if(device<nMaxDevice)
	{
		if(hDevice[device] != INVALID_HANDLE_VALUE )
		{
			/*
				DeviceIoControl(hDevice[device],
							WTDRIVER_SET_BUS_DEVICE_NUMBER,
							pDeviceInfo,
							sizeof(struct	WT_Device_Info),
							NULL,
							NULL,  
							&nWrite,
							NULL);
							*/
		}
	}
    return nWrite;
}



BOOL WtPci_Open(struct PCI_CONFIG_HEADER_0 *pci_config,UINT8 index)
{
	
	UINT32 i=0;
	UINT32 membase = 0;
	UINT8 io_n   = 0;
	UINT8 mem_n  = 0;
	int busno    = 0;
	int deviceno = 0;
	int funcno   = 0;
	pci_config->VendorID = PCI_VENID;
	pci_config->DeviceID = PCI_DEVID;
	if(pciFindDevice(pci_config->VendorID,pci_config->DeviceID,index,&(busno),\
		&(deviceno),&(funcno)) == ERROR)
	{

		printf("PCI do not found!\n");
		return ERROR;

	}
	
	/************************note******************
	*for this 153-bored, there has 3 memory address.mybe there is another way to
	*find out wether the address is valide or not.
	*the last bit of the memory address is flag of the kind of this address.0 for memory, 1 for IO
	****************************/
	pciConfigInByte(busno,deviceno,funcno,RevisionID_ADDR , &pci_config->RevisionID);
	pciConfigInByte(busno,deviceno,funcno,BIST_ADDR , &pci_config->BIST);
	pciConfigInByte(busno,deviceno,funcno,BaseClass_ADDR , &pci_config->BaseClass);
	pciConfigInByte(busno,deviceno,funcno,CacheLineSize_ADDR , &pci_config->CacheLineSize);
	pciConfigInLong(busno,deviceno,funcno,CardBusCISPtr_ADDR , (UINT32*)&pci_config->CardBusCISPtr);
	pciConfigInWord(busno,deviceno,funcno,Command_ADDR , &pci_config->Command);
	pciConfigInByte(busno,deviceno,funcno,HeaderType_ADDR , &pci_config->HeaderType);
	pciConfigInByte(busno,deviceno,funcno,InterruptLine_ADDR , &pci_config->InterruptLine);
	pciConfigInByte(busno,deviceno,funcno,InterruptPin_ADDR , &pci_config->InterruptPin);
	pciConfigInByte(busno,deviceno,funcno,LatencyTimer_ADDR , &pci_config->LatencyTimer);
	pciConfigInByte(busno,deviceno,funcno,MaximumLatency_ADDR , &pci_config->MaximumLatency);
	pciConfigInByte(busno,deviceno,funcno,MinimumGrant_ADDR , &pci_config->MinimumGrant);
	pciConfigInByte(busno,deviceno,funcno,ProgIf_ADDR , &pci_config->ProgIf);
	pciConfigInLong(busno,deviceno,funcno,ROMBaseAddress_ADDR , (UINT32*)&pci_config->ROMBaseAddress);
	pciConfigInWord(busno,deviceno,funcno,Status_ADDR , &pci_config->Status);
	pciConfigInByte(busno,deviceno,funcno,SubClass_ADDR , &pci_config->SubClass);
	pciConfigInWord(busno,deviceno,funcno,SubsystemID_ADDR , &pci_config->SubsystemID);
	pciConfigInWord(busno,deviceno,funcno,SubsystemVendorID_ADDR , &pci_config->SubsystemVendorID);
	pci_bord[index].intNum= pci_config->InterruptLine;
	

	for(i=0; i<6; i++)
	{
		
		if(pciConfigInLong(busno,deviceno,funcno,\
			PCI_ADDRBASE + i<<2 , &membase)== ERROR)  /*configInLong is 32bits addr, configInByte is 8bits addr*/
		{
			printf("find PCI address error!\n");
			return ERROR;
		}
		
		if(membase !=0)
		{
			pci_config->BaseAddresses[i] = membase;
			if(membase&1 == 1)
			{
				
				/*PCI_ID->ioBase[io_n] = membase & 0xfffffff8;*/				
				pCHAR_PCI_BAR[index][i] = (PCHAR)(membase & 0xfffffff8);
				io_n++;
			}
			else
			{
				
				/*PCI_ID->memBase[mem_n] = membase & 0xfffffff0;*/
				pCHAR_PCI_BAR[index][i] = (PCHAR)(membase & 0xfffffff0);
				mem_n++;		
			}
				pci_bord[index].pcimem[i] = pCHAR_PCI_BAR[index][i];
			membase = 0;
		}
		
	}

	return OK;
	
}
BOOL WtPci_IntHandle(int DEVICE_NUM)
{
    while(semTake(pci_bord[DEVICE_NUM].semPci,WAIT_FOREVER)!=ERROR)
	{

		if(Close_Flag[DEVICE_NUM]==1)
		{
			//if(WaitForSingleObject(hEvent[DEVICE_NUM],1)==WAIT_OBJECT_0)
			{
				for(UINT idx=0;idx<nMax_Lowlevle_Handle;idx++)  /*search every channle for handle*/
				{
					if(pUserHandle[DEVICE_NUM][idx]!=NULL)
					{
						pUserHandle[DEVICE_NUM][idx](DEVICE_NUM);
					}
				}
			}
		}
		else if(Close_Flag[DEVICE_NUM]==2)
		{
			Close_Flag[DEVICE_NUM]=0;
			break;
		}
    }
    return 0;
}

BOOL WtPci_Initial(UINT device)
{

	if(pci_bord[device].semIntFlag == 1)
	{
		semDelete(pci_bord[device].semPci);
	}
	memset((&(pci_config_lo[device])), 0,sizeof(struct PCI_CONFIG_HEADER_0));
	memset((&(pci_bord[device])),0,sizeof(struct pciBoardIndex));
	/*for(pciIndex = 0; pciIndex <nMaxDevice; pciIndex++)
	{
		pci_config_lo[pciIndex].
	}*/
	return OK;
	
}
/*BOOL WtPci_IntConnect(UINT inum, VOIDFUNCPTR* intFun,UINT device)
{
	pciIntConnect(INUM_TO_IVEC(inum), (VOIDFUNCPTR*)intFun,device);
}*/
int WtPci_IntFun(UINT device)
{
//	logMsg("**********************************we have an interupt from PCI device!\n",0,0,0,0,0,0);

	sysIntDisablePIC(pci_bord[device].intNum);
	//intDisable(pci_bord[device].intNum);
	//sysAuxClkDisable();

	//for(pciIndex=0;pciIndex<nMaxDevice;pciIndex++)
	{
		if(*(UINT32*)(pci_bord[device].pcimem[PCI_BAR1]+0x41fff0) & 0x1 == 1)
		{
			*(UINT32*)(pci_bord[device].pcimem[PCI_BAR1]+0x400000) = 0x10;
			*(UINT32*)(pci_bord[device].pcimem[PCI_BAR1]+0x41fff0) = 0x1;
			//logMsg("**********************************we have an interupt from PCI device!\n",0,0,0,0,0,0);
			semGive(pci_bord[device].semPci);
			
		}
	}
	sysIntEnablePIC(pci_bord[device].intNum);
	//intEnable(pci_bord[device].intNum);
	//sysAuxClkEnable();
}
BOOL WtPci_Close(UINT device)
{

	//intDisable(pci_bord[device].intNum);	//winie
	if(Thread[device]!=taskIdSelf())
	{
		taskDelete(Thread[device]);	
	}
	semDelete(pci_bord[device].semPci);
	pci_bord[device].semIntFlag = 0;
	return OK;
}
BOOL WtPci_CloseAll(void)
{

	int pciIndex;
	for(pciIndex=0; pciIndex<nMaxDevice;pciIndex++)
	{
		if(Thread[pciIndex]!=INVALID_HANDLE_VALUE)
		{
		intDisable(pci_bord[pciIndex].intNum);	
		if(Thread[pciIndex]!=taskIdSelf())
		{
			taskDelete(Thread[pciIndex]);	
		}
		semDelete(pci_bord[pciIndex].semPci);
		pci_bord[pciIndex].semIntFlag = 0;
		}
	}
	return OK;
}


UINT WT_Read32(UINT device,PUINT ptr,UINT ofs,UINT num,UINT PCI_BAR)
{
	if (ofs <= 0xff)
	{
		printf("you are not allowed to read this address by this function\n"
				"please try WT_PCI_Read()");
	}
	memcpy( ptr,(UINT32*)(pci_bord[device].pcimem[PCI_BAR] + ofs), num); /*WORD COPY*/
	return OK;
}
UINT WT_Write32(UINT device,PUINT ptr,UINT ofs,UINT num,UINT PCI_BAR)
{
	if (ofs <= 0xff)
	{
		printf("you are not allowed to read this address by this function\n"
				"please try WT_PCI_Read()");
	}
	memcpy((UINT32*) (pci_bord[device].pcimem[PCI_BAR] + ofs), ptr, num); /*WORD COPY*/
	return OK;
}
